package com.xinlong.shop.api.promotion;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.xinlong.shop.core.promotion.entity.DetailStatusEnum;
import com.xinlong.shop.core.promotion.entity.PutSaleOrder;
import com.xinlong.shop.core.promotion.entity.dto.RushPurchaseDetailDTO;
import com.xinlong.shop.core.promotion.service.IPutSaleOrderService;
import com.xinlong.shop.core.promotion.service.IRushPurchaseDetailService;
import com.xinlong.shop.framework.common.R;
import com.xinlong.shop.framework.service.ISysSettingService;
import com.xinlong.shop.framework.weixin.service.WeiXinMpService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 上架订单列表 前端控制器
 * </p>
 *
 * @author Sylow
 * @since 2023-03-29
 */
@RestController
@RequestMapping("/buyer/promotion/put-sale-order")
public class BuyerPutSaleOrderController {

    private final IPutSaleOrderService putSaleOrderService;
    private final IRushPurchaseDetailService rushPurchaseDetailService;
    private final ISysSettingService sysSettingService;
    private final WeiXinMpService weiXinMpService;

    public BuyerPutSaleOrderController(IPutSaleOrderService putSaleOrderService, IRushPurchaseDetailService rushPurchaseDetailService, ISysSettingService sysSettingService, WeiXinMpService weiXinMpService) {
        this.putSaleOrderService = putSaleOrderService;
        this.rushPurchaseDetailService = rushPurchaseDetailService;
        this.sysSettingService = sysSettingService;
        this.weiXinMpService = weiXinMpService;
    }

    /**
     *
     * @param id 抢购明细id
     * @return
     */
    @RequestMapping(value = "/get-order-info", method = RequestMethod.GET)
    public R getOrderInfo(Integer id){
        RushPurchaseDetailDTO pd = rushPurchaseDetailService.findDTOById(id);
        // 检查抢购状态
        if (pd.getStatus() != DetailStatusEnum.CONFIRM.getCode()) {
            return R.error("状态不正确");
        }
        // 获取系统配置
        Map<String, Object> setting = sysSettingService.getSetting();
        Double priceMarkup = (Double) setting.get("priceMarkup");
        Double putSalePrice = (Double) setting.get("putSalePrice");

        // 计算价格和服务费
        BigDecimal price = getPrice(pd.getPrice(), priceMarkup);
        BigDecimal priceService = getServicePrice(pd.getPrice(), putSalePrice);

        // 设置费用精度
        Double priceDouble = price.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
        Double priceServiceDouble = priceService.setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();

        Map<String, Object> orderInfo = new HashMap<>();
        orderInfo.put("originalPrice", pd.getPrice());
        orderInfo.put("price", priceDouble);
        orderInfo.put("servicePrice", priceServiceDouble);
        return R.success("操作成功", orderInfo);
    }

    /**
     * 上架操作
     * @param id 抢购明细id
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.POST)
    public R save(Integer id, String code, String openid, BigDecimal price, BigDecimal servicePrice){
        RushPurchaseDetailDTO pd = rushPurchaseDetailService.findDTOById(id);
        // 检查抢购状态
        if (pd.getStatus() != DetailStatusEnum.CONFIRM.getCode()) {
            return R.error("状态不正确");
        }

        // 获取系统配置
        Map<String, Object> setting = sysSettingService.getSetting();
        Double priceMarkup = (Double) setting.get("priceMarkup");
        Double putSalePrice = (Double) setting.get("putSalePrice");

        // 这里会出现并发问题，之后要改造进Service里  并且加锁(前端加loading，防止重复提交)
        PutSaleOrder putSaleOrder = this.putSaleOrderService.findByDetailId(id);
        // 如果有数据了 就不用再新增了， 直接使用
        if (putSaleOrder == null) {



            // 计算价格和服务费
            BigDecimal sellPrice = getPrice(pd.getPrice(), priceMarkup);
            int flag = price.compareTo(sellPrice);
            // 如果手动价格小于 就使用手动价格，否则使用最高价格
            if (flag == -1 || flag == 0) {
                sellPrice = price;
            }
            // 服务费是购买的价格来计算
            BigDecimal priceService = getServicePrice(pd.getPrice(), putSalePrice);

            flag = servicePrice.compareTo(priceService);
            // 如果服务费价格小于或者等于前端调整的服务费 就使用使用自动计算最高价格
            if (flag == -1 || flag == 0) {
                priceService = servicePrice;
            }

            // 设置费用精度
            sellPrice = sellPrice.setScale(0, BigDecimal.ROUND_HALF_UP);
            priceService = priceService.setScale(0, BigDecimal.ROUND_HALF_UP);


            PutSaleOrder order = new PutSaleOrder();
            order.setOrderSn(pd.getOrderSn());
            order.setOriginalPrice(pd.getPrice());
            order.setNewPrice(sellPrice);
            order.setServicePrice(priceService);
            order.setRushPurchaseDetailId(pd.getId());
            order.setRushPurchaseId(pd.getRushPurchaseId());
            order.setMemberId(pd.getBuyerId());

            boolean result = this.putSaleOrderService.savePutSaleOrder(order);
            if (result) {
                putSaleOrder = order;

            } else {
                return R.error("操作失败，请重试");
            }
        } else {
            // 状态不等于0 就是已经支付过
            if (putSaleOrder.getStatus() != 0) {
                return R.error("请勿重复操作", putSaleOrder);
            }

            /**
             * 这块代码与上面代码重复 后期可以优化
             */
            // 计算价格和服务费
            BigDecimal sellPrice = getPrice(pd.getPrice(), priceMarkup);
            int flag = price.compareTo(sellPrice);
            // 如果手动价格小于或者等于 就使用手动价格，否则使用最高价格
            if (flag == -1 || flag == 0) {
                sellPrice = price;
            }

            // 服务费是购买的价格来计算
            BigDecimal priceService = getServicePrice(pd.getPrice(), putSalePrice);
            flag = servicePrice.compareTo(priceService);
            // 如果服务费价格小于或者等于前端调整的服务费 就使用使用自动计算最高价格
            if (flag == -1 || flag == 0) {
                priceService = servicePrice;
            }

            // 设置费用精度
            sellPrice = sellPrice.setScale(0, BigDecimal.ROUND_HALF_UP);
            priceService = priceService.setScale(0, BigDecimal.ROUND_HALF_UP);

            // 更新价格
            putSaleOrder.setNewPrice(sellPrice);
            putSaleOrder.setServicePrice(priceService);
            boolean result = this.putSaleOrderService.update(putSaleOrder, putSaleOrder.getId());
            if (!result) {
                return R.error("操作失败，请重试");
            }
        }

        Map<String,Object> settings = sysSettingService.getSetting();
        Map<String, Object> result = new HashMap<>();

        boolean openWeixinPay = (boolean) settings.get("openWeixinPay");
        if (openWeixinPay) {
            if (StrUtil.isBlank(openid)) {
                openid = weiXinMpService.getOpenId(code);
                if (StrUtil.isBlank(openid)) {
                    return R.error("操作失败，请重试");
                }
            }
            PrepayWithRequestPaymentResponse response = weiXinMpService.pay(putSaleOrder.getOrderSn(), openid,
                    putSaleOrder.getServicePrice(), "寄售服务费");

            result.put("openWeixinPay", openWeixinPay);
            result.put("response", response);
            result.put("openid", openid);   // 返回前端做缓存，暂时不保存到后端
        } else {
            result.put("openWeixinPay", openWeixinPay);
        }

        return R.success("操作成功", result);

    }

    /**
     * 获取新上架价格
     * @param price 原价
     * @param priceMarkup 涨幅
     * @return
     */
    private BigDecimal getPrice(BigDecimal price, Double priceMarkup){

        // 配置中是整数 需要除以100
        Double divisor = 100D;
        priceMarkup = NumberUtil.div(priceMarkup, divisor, 3);

        // 新价格= 原价+原价*增幅百分比
        price = NumberUtil.add(price,NumberUtil.mul(price, priceMarkup));


        return price;
    }

    /**
     * 获取服务费金额
     * @param price 商品价格
     * @param putSalePrice 服务费百分比
     * @return
     */
    private BigDecimal getServicePrice(BigDecimal price, Double putSalePrice){

        // 配置中是整数 需要除以100
        Double divisor = 100D;
        putSalePrice = NumberUtil.div(putSalePrice, divisor, 3);

        // 服务费=新价格*百分比
        BigDecimal servicePrice = NumberUtil.mul(price, putSalePrice);

        return servicePrice;
    }

}
